/**
 * @file      subprocess.h
 * @brief     
 * @details   
 * @author    liuri
 * @date      Mon 21 Dec 2020 07:01:40 AM UTC
 * @version   V1.0 
 * @copyright Copyright LiuRi, All Rights Reserved 
 ************************************************************************
 * @attention
 * 硬件平台: X86_64 \n
 * 
 * @par 修改日志
 * <table>
 * <tr><th> Date          <th> Version   <th> Description
 * <tr><td> 2020/04/28    <td> 1.0       <td> 创建初始版本
 * </table>
 * 
 ************************************************************************
 */



#ifndef __SUBPROCESS_H__
#define __SUBPROCESS_H__

#include <sys/types.h>
#include <unistd.h>
#include <string.h>


#define ARGS_MAX_NUMBER     256                     /** 参数个数 */
#define ENV_MAX_NUMBER      256                     /** 环境个数 */
#define UNLIMITED           -1                      /** 资源不限制 */





/**
 * @brief 进程返回值 
 */
enum PROCESS_RET {
    SUCCESS = 0,
    INVALID_CONFIG = -1,
    FORK_FAILED = -2,
    PTHREAD_FAILED = -3,
    WAIT_FAILED = -4,
    ROOT_REQUIRED = -5,
    LOAD_SECCOMP_FAILED = -6,
    SETRLIMIT_FAILED = -7,
    DUP2_FAILED = -8,
    SETUID_FAILED = -9,
    EXECVE_FAILED = -10,
    SPJ_ERROR = -11
};


/**
 * @brief 子进程运行结果
 */
enum PROCESS_RUN{
    WRONG_ANSWER = -1,
    CPU_TIME_LIMIT_EXCEEDED = 1,
    REAL_TIME_LIMIT_EXCEEDED = 2,
    MEMORY_LIMIT_EXCEEDED = 3,
    RUNTIME_ERROR = 4,
    SYSTEM_ERROR = 5
};



/**
 * @brief 进程相关配置值
 */
struct process_config {
    int max_cpu_time;                   /** 最大允许的CPU使用时间，秒为单位 */
    int max_real_time;                  /** 实际运行时间，通过线程控制，超时直接杀死 */
    long max_memory;                    /** 进程的最大虚内存空间，字节为单位 */
    long max_stack;                     /** 进程堆栈资源限制 */
    int max_process_number;             /** 用户可拥有的最大进程数 */
    long max_output_size;               /** 进程可建立的文件的最大长度。如果进程试图超出这一限制时，核心会给其发送SIGXFSZ信号， */ 
    int memory_limit_check_only;        /** 是否设置最大虚内存空间 */
    char *exe_path;                     /** 执行文件路径 */
    char *input_path;                   /** 输入路径 */
    char *output_path;                  /** 正常输出路径 */
    char *error_path;                   /** 错误输出路径 */
    char *args[ARGS_MAX_NUMBER];        /** 命令行参数，在调用 execve 时传入 */
    char *env[ENV_MAX_NUMBER];          /** 环境信息: RUN=..., */
    char *log_path;                     /** 日志路径 */
    char *seccomp_rule_name;            /** 沙箱名字 */
    int   uid;                          /** 设置调用进程的有效用户 ID uid_t */
    int   gid;                          /** 设置调用进程的有效组 ID gid_t */
};





/**
 * @brief 进程状态
 */
struct process_state {
    int cpu_time;       /** CPU 运行时间: 子进程运行时间 */
    int real_time;      /** CPU 实际运行时间 */
    long memory;        /** 使用的内存大小 */
    int signal;         /** 退出信号 */
    int exit_code;      /** 退出码 */
    int error;          /** 进程返回值 PROCESS_RET 部分值， ERROR_EXIT 赋值 */
    int result;         /** 子进程运行结果: PROCESS_RUN  */
};

#endif

